using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;

public partial class Captcha : System.Web.UI.Page
{
    private string text;
    private const int width = 225;
    private const int height = 50;
    private string familyName;
    private Bitmap image;

    private Random random = new Random();
    private void SetFamilyName(string familyName)
    {
        try
        {
            Font font = new Font(this.familyName, 12F);
            this.familyName = familyName;
            font.Dispose();
        }
        catch (Exception ex)
        {
            this.familyName = System.Drawing.FontFamily.GenericSerif.Name;
        }
    }

    private void GenerateImage()
    {
        // Create a new 32-bit bitmap image.
        Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

        // Create a graphics object for drawing.
        Graphics g = Graphics.FromImage(bitmap);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        Rectangle rect = new Rectangle(0, 0, width, height);

        // Fill in the background.
        HatchBrush hatchBrush = new HatchBrush(HatchStyle.WideDownwardDiagonal, Color.LightGray, Color.White);
        g.FillRectangle(hatchBrush, rect);

        // Set up the text font.
        SizeF size;
        float fontSize = rect.Height + 1;
        Font font;
        // Adjust the font size until the text fits within the image.
        do
        {
            fontSize--;
            font = new Font(familyName, fontSize, FontStyle.Bold);
            size = g.MeasureString(text, font);
        } while ((size.Width > rect.Width) && (size.Height > rect.Height));

        // Set up the text format.
        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;

        // Create a path using the text and warp it randomly.
        GraphicsPath path = new GraphicsPath();
        path.AddString(text, font.FontFamily, (int)font.Style, font.Size, rect, format);
        float v = 5F;
        PointF[] points =
			{
				new PointF(random.Next(rect.Width) / v, random.Next(rect.Height) / v),
				new PointF(rect.Width - random.Next(rect.Width) / v, random.Next(rect.Height) / v),
				new PointF(random.Next(rect.Width) / v, rect.Height - random.Next(rect.Height) / v),
				new PointF(rect.Width - random.Next(rect.Width) / v, rect.Height - random.Next(rect.Height) / v)
			};

        Matrix matrix = new Matrix();
        matrix.Translate(0F, 0F);
        path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

        Pen mPen = new Pen(Color.DarkGray, 3);
        g.DrawLine(mPen, random.Next(20) + 10, random.Next(40) + 5, random.Next(20) + 90, random.Next(40) + 5);
        g.DrawLine(mPen, random.Next(20) + 90, random.Next(40) + 5, random.Next(20) + 170, random.Next(40) + 5);
        mPen.Dispose();

        // Draw the text.
        hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, Color.LightGray, Color.DarkGray);
        g.FillPath(hatchBrush, path);

        // Add some random noise.
        int m = Math.Max(rect.Width, rect.Height);
        for (int i = 0; i < (int)(rect.Width * rect.Height / 40F); i++)
        {
            int x = random.Next(rect.Width);
            int y = random.Next(rect.Height);
            int w = random.Next(m / 50);
            int h = random.Next(m / 50);
            g.FillEllipse(hatchBrush, x, y, w, h);
        }

        // Clean up.
        font.Dispose();
        hatchBrush.Dispose();
        g.Dispose();

        // Set the image.
        image = bitmap;
    }

    private void Page_Load(object sender, System.EventArgs e)
    {
        text = "";
        int len = random.Next(2) + 5;
        int i;
        for (int t = 0; t < len; t++)
        {
            i = random.Next(61);
            if (i < 9) i += 49;
            else if (i < 35) i += 56;
            else if (i < 61) i += 62;
            else i = 0;
            if(i!=0) text += Char.ConvertFromUtf32(i);
        }

        SetFamilyName("Century Schoolbook");
        Page.Session.Add("CaptchaText", text);
        GenerateImage();

        this.Response.Clear();
        this.Response.ContentType = "image/jpeg";
        image.Save(this.Response.OutputStream, ImageFormat.Jpeg);

        image.Dispose();       
    }
}
